// pages/chat/chat.ts
import { getRecommendListByTitle } from '../../api/assistant';
import { getCaseDetail } from '../../api/case';
import { getVideoDetail } from '../../api/video';
import { cardType } from '../../utils/card';
import { flow } from '../../utils/flowtype';
import { login } from '../../utils/login'

const plugin = requirePlugin('WechatSI');
const manager = plugin.getRecordRecognitionManager();

Page({
  /**
   * 页面的初始数据
   */
  data: <any>{
    selectlistHide: false, //列表展示
    replyed: true, //提问中
    content: "", //问题

    tagstype: true, //输入框高度类名
    voiceing: false, //是否处于语音输入中
    voicedelay: true, //语音图片延迟展示否则可能会闪现

    originAnswers: [],
    answers: [], // 业务助手内容数据
    probe: [], //追问的内容数据
    waiting: "", //等候语

    article: "", //markdown
    problemlogo: "",  //提问的头像
    newContent: "", //流式输出文本
    chatdata: [], //获取chat的url之类的数据

    voice_type: "", //合成声音的音色
    novoice: true, //是否播放语音
    voicelist: '', //音频的列表数据

    requestTask: "", //请求实例

    dreplyedList: [], // 给列表传递的内容数据
    bottomId: '',
    time: null
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    this.setData({
      problemlogo: "我",
      waiting: this.markdown("思考中，请稍后...")
    })
    this.initRecord()
    this.getRouterdata()
    wx.onKeyboardHeightChange(res => {
      console.log(res.height)
    })
  },

  getRouterdata() {
    const types = {
      '0': 'AI 问指南',
      '1': 'AI 问专家',
      '2': 'AI 查资讯',
    }
    const eventChannel = this.getOpenerEventChannel()
    eventChannel.on('acceptDataFromOpenerPage', (data) => {
      if (!data || !data.currentGuide) {
        return
      }
      const guide = data.currentGuide

      this.setData({
        currentGuide: {
          ...guide,
          type: types[guide.type]
        }
      })
      this.chatinit();
    })
  },

  // 获取chat数据
  async chatinit() {
    this.addAnswersList({
      role: "assistant",
      content: this.markdown(`您好，我是您的《${this.data.currentGuide.name}》AI助手，有什么可以帮助您？`)
    })

    this.saveOriginAnswerList({
      role: "assistant",
      content: `您好，我是您的《${this.data.currentGuide.name}》AI助手，有什么可以帮助您？`
    })

    let recommend: any = this.data.currentGuide.problemList || []
    this.setData({
      probe: recommend
    })
  },

  // 获取输入框内容
  handleInput: function (event: any) {
    this.setData({
      content: event.detail.value.trim(),
    })
  },

  // 获取当前时间
  getTime() {
    var currentTime = new Date();
    var year = currentTime.getFullYear()
    var month = (currentTime.getMonth() + 1).toString().padStart(2, '0');
    var day = currentTime.getDate().toString().padStart(2, '0');
    return year + '-' + month + '-' + day;
  },

  back() {
    wx.navigateBack({
      delta: 1  // delta 值为 1 时表示关闭当前页面
    });
  },

  getAliDeep() {
    return {
      url: 'https://ark.cn-beijing.volces.com/api/v3/chat/completions',
      token: '30f52bbe-e5ab-489d-acb6-537191771013',
      data: {
        "model": "deepseek-v3-250324",
        "stream": true,
        "messages": this.data.originAnswers
      }
    }
  },
  getCaCa() {
    return {
      url: 'https://caca.zn-care.com/api/v1/chat/completions/ask',
      token: wx.getStorageSync('token'),
      data: {
        "modelId": this.data.currentGuide.id,
        "stream": true,
        "messages": this.data.originAnswers
      }
    }
  },

  // 发送请求
  async getFastGPTAns() {
    if (!this.data.replyed) {
      wx.showToast({
        title: '等待对话结束',
        icon: 'error',
        duration: 1000,
      })
      return
    }
    if (this.data.content == "") {
      wx.showToast({
        title: '问题不能为空',
        icon: 'error',
        duration: 1000,
      })
      return
    }

    // 等待60秒后，恢复可以输入
    this.setData({
      time: setTimeout(() => {
        this.setData({
          replyed: true
        })
      }, 60000)
    })

    if (this.data.replyed) {
      this.setData({
        replyed: false,
      })

      // 提问的内容显示出来
      this.addAnswersList({
        role: "user",
        problem: this.data.content
      })

      // 等待中内容显示出去
      this.addAnswersList({
        role: "assistant",
        content: this.data.waiting
      })
      this.saveOriginAnswerList({
        role: "user",
        content: this.data.content
      })

      const { url, token, data } = this.getCaCa()
      const requestTask = wx.request({
        url,
        method: "POST",
        enableChunked: true,
        header: {
          "Authorization": `Bearer ${token}`,
          "Content-Type": "application/json",
        },
        data,
        fail: () => {
          clearTimeout(this.data.time)
          this.setData({
            time: null,
            replyed: true
          })
        }
      })

      this.setData({
        requestTask: requestTask
      })

      // 监听数据分块接收事件，流式输出
      requestTask.onChunkReceived(async (response) => {
        let newContent = this.data.newContent
        let result = flow(response, newContent, this.data.answers)

        this.setData({
          newContent: result.newContent,
          answers: result.answers
        })

        this.throttleScrollBottom()

        if(result.stop){
          await this.chatComplete()
        }
      });

    }
  },

  async chatComplete(){
    clearTimeout(this.data.time)
    const answers = [
      ...this.data.answers
    ]
    const answer = answers[answers.length - 1]
    let type: string = ''
    if (answer.newContent) {
      try {
        const c = JSON.parse(answer.newContent)
        type = cardType[c.cardType]
        if (type) {
          answer.newContent = {
            ...c,
            type
          }

          this.setData({
            answers
          })
        }

        if (type && type === 'recommend') {
          // 根据title查询
          const list = answer.newContent.content.text.map(item => item.firstLine.replace('助手', ''))
          const res = await getRecommendListByTitle(JSON.stringify(list))
          if (res?.rows && res?.rows.length > 0) {
            const findedAnswer = answer.newContent.content.text.map(item => {
              const assistant = res.rows.find(a => a.title === item.firstLine.replace('助手', ''))
              if (assistant) {
                return {
                  ...item,
                  ...assistant
                }
              } else {
                return {
                  ...item
                }
              }
            })
            if (findedAnswer) {
              answer.newContent.content.text = findedAnswer
            }
            this.setData({
              answers
            })
          }
        }     
      } catch (error) {
        console.log(error, this.data.answers[this.data.answers.length - 1])
      }
    }

    this.setData({
      time: null,
      replyed: true
    })

    this.saveOriginAnswerList({
      role: "assistant",
      content: this.data.newContent
    })

    this.setData({
      newContent: ""
    })
    setTimeout(() => {
      this.scrollBottom()

      if(!type && answer.newContent.indexOf('指南相关内容') > -1){
        this.setData({
          content: '查找相关内容'
        })
        this.getFastGPTAns()
      }
    }, 500)
  },

  enterAssistant(e: any) {
    const { assistant } = e.currentTarget.dataset

    wx.navigateTo({
      url: '/pages/chat/chat',
      events: {
        acceptDataFromOpenerPage: function (data: any) {
          console.log(data)
        }
      },
      success: (res) => {
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          currentGuide: {
            ...assistant,
            ...assistant.modelVo,
            name: assistant.title
          }
        })
      }
    });
  },

  // 单条资讯
  enterLink(e: any) {
    let title = e.currentTarget.dataset.title
    if (title) {
      this.setData({
        content: `资讯标题：${title}`
      })
      this.getFastGPTAns()
    }
  },

  // 进入视频
  enterVideo: async (e: any) => {
    const item = e.currentTarget.dataset.item

    if (item.id) {
      const detail = await getVideoDetail({
        videoId: item.id
      })

      if (detail.data) {
        wx.navigateTo({
          url: '/pages/guideDetail/guideDetail',
          success: (res) => {
            res.eventChannel.emit('acceptDataFromOpenerPage', detail.data)
          }
        });
      } else {
        wx.showToast({
          title: '查询视频失败',
          icon: 'error',
          duration: 2000
        })
      }
    }

  },

  // 进入问答
  enterQa(e: any) {
    const item = e.currentTarget.dataset.item

    wx.navigateTo({
      url: '/pages/qaDetail/qaDetail',
      success: (res) => {
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          id: item.id
        })
      }
    });
  },

  // 进入案例
  enterCase: async (e: any) => {
    const item = e.currentTarget.dataset.item

    if (item.id) {
      const detail = await getCaseDetail({
        caseId: item.id
      })

      if (detail.data) {
        wx.navigateTo({
          url: '/pages/caseDetail/caseDetail',
          success: (res) => {
            res.eventChannel.emit('acceptDataFromOpenerPage', detail.data)
          }
        });
      } else {
        wx.showToast({
          title: '查询案例失败',
          icon: 'error',
          duration: 2000
        })
      }
    }
  },

  // 点击追问提问
  probeClick(e: any) {
    let index = e.currentTarget.dataset.index
    let text = this.data.probe[index]
    this.setData({
      content: text
    })
    this.getFastGPTAns()
  },

  // 问答模式添加数据
  addAnswersList(message: any) {
    const newList: any = [...this.data.answers, message]
    this.setData({
      answers: newList,
    })

    setTimeout(() => {
      this.clearTextarea()
      this.scrollBottom()
    }, 30)
  },

  saveOriginAnswerList(message: any) {
    const newList: any = [...this.data.originAnswers, message]
    this.setData({
      originAnswers: newList,
    })
  },

  lastScrollTime: '',

  throttleScrollBottom() {
    const that = this;
    const step = 600;
    if (!this.data.lastScrollTime || (Date.now() - this.data.lastScrollTime) > step) {
      that.scrollBottom()
      this.data.lastScrollTime = Date.now();
    } else {
      clearTimeout(this.data.scrollTimeout);
      this.data.scrollTimeout = setTimeout(() => {
        that.scrollBottom();
      }, step - (Date.now() - this.data.lastScrollTime));
    }
  },

  scrollBottom() {
    this.setData({
      bottomId: 'dialogBottom'
    });
  },

  // 删除输入框
  clearTextarea: function () {
    this.setData({
      content: "",
    })
  },

  // markdown解析
  markdown(content: string) {
    let towxml = require('../../towxml/index')
    let result = towxml(content, 'markdown')
    return result
  },

  // 输入框高度动画
  changeFooterStyle() {
    this.setData({
      tagstype: !this.data.tagstype, //输入框高度类名
    })
  },

  //识别语音 -- 初始化
  initRecord: function () {
    const that = this;

    manager.onStop = function (res: any) {
      if (res.result == '') {
        wx.showModal({
          title: '提示',
          content: '听不清楚，请重新说一遍！',
          showCancel: false,
          success: function (res: any) { }
        })
        return;
      }
      that.setData({
        content: res.result
      })
    }
  },

  // 长按语音时执行
  touchStart() {
    // 语音开始识别
    manager.start({
      lang: 'zh_CN',// 识别的语言，目前支持zh_CN en_US zh_HK sichuanhua
    })
    this.setData({
      voicedelay: false
    })
    setTimeout(() => {
      this.setData({
        voiceing: !this.data.voiceing,
      })
    }, 300)
  },

  // 松开语音时执行
  touchEnd() {
    // 语音结束识别
    manager.stop();
    this.setData({
      voiceing: !this.data.voiceing,
      voicedelay: true
    })
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    login()
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    try {
      this.data.requestTask.abort()
    } catch (error) {
    }
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
    return {
      "title": "",
      "path": `pages/home/home`,
      "imageUrl": "/static/img/home.jpg"
    }
  }
})